#include "Eventfd.hpp"
#include <func.h>

namespace  ln{

Eventfd::Eventfd(EventCallback && cb)
:_eventfd(createEventfd())
,_cb(std::move(cb))
,_isStarted(false)
{

}
    
Eventfd::~Eventfd(){
    if(_eventfd > 0){
        close(_eventfd);
    }
}

//运行在子线程中，对_eventfd进行监听
void Eventfd::start(){
    struct pollfd fd;
    memset(&fd,0,sizeof(fd));
    fd.fd = _eventfd;
    fd.events = POLLIN;

    _isStarted = true;
    while(_isStarted){
        int nready = poll(&fd,1,5000);
        if(nready == -1 && errno == EINTR){
            continue;
        }else if(nready == -1){
            perror("poll");
            return;
        }else if(nready == 0){
            printf("timeout\n");
        }else{
            //触发_eventfd的读事件
            handleReadEvent();

            //执行任务
            if(_cb){
                _cb();
            }
        }
    }
}
    
void Eventfd::wakeup(){
    uint64_t one = 1;
    int ret = write(_eventfd,&one,sizeof(one));
    if(ret != sizeof(one)){
        perror("write");
    }
}
    
void Eventfd::stop(){
    _isStarted = false;
}

int Eventfd::createEventfd(){
    int fd = eventfd(0,0);
    if(fd < 0){
        perror("eventfd");
    }
    return fd;
}
    
void Eventfd::handleReadEvent(){
    uint64_t howmany = 0;
    int ret = read(_eventfd,&howmany,sizeof(howmany));
    if(ret != sizeof(howmany)){
        perror("read");
    }
}

}//end of namespace ln
